package com.atguigu.controller;


import com.atguigu.client.OrderFeignClient;
import com.atguigu.client.UserFeignClient;
import com.atguigu.constant.MqConst;
import com.atguigu.constant.RedisConst;
import com.atguigu.entity.*;
import com.atguigu.result.RetVal;
import com.atguigu.result.RetValCodeEnum;
import com.atguigu.service.SeckillProductService;
import com.atguigu.util.AuthContextHolder;
import com.atguigu.util.MD5;
import com.atguigu.utils.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author GuoJH
 * @since 2021-09-13
 */
@RestController
@RequestMapping("/seckill")
public class SeckillProductController {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SeckillProductService seckillProductService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private OrderFeignClient orderFeignClient;
    //1.秒杀商品列表的展示  从redis中获取
    @GetMapping("/queryAllSeckillProduct")
    public RetVal queryAllSeckillProduct(){
        List<SeckillProduct> seckillProductList = redisTemplate.boundHashOps(RedisConst.SECKILL_PRODUCT).values();
        return RetVal.ok(seckillProductList);
    }
    //2.秒杀商品的详情信息  根据skuId获取秒杀商品
    @GetMapping("/getSeckillProductBySkuId/{skuId}")
    public RetVal getSeckillProductBySkuId(@PathVariable Long skuId){
        SeckillProduct seckillProduct = seckillProductService.getSeckillProductBySkuId(skuId);
        return RetVal.ok(seckillProduct);
    }
    //3.生成抢购码 防止用户直接跳过商品详情进入秒杀地址
    @GetMapping("/generateSeckillCode/{skuId}")
    public RetVal generateSeckillCode(@PathVariable Long skuId, HttpServletRequest request){
        //b.判断用户是否登录
        String userId = AuthContextHolder.getUserId(request);
        if(StringUtils.isNotEmpty(userId)){
            //c.从缓存中查询秒杀商品信息
            SeckillProduct seckillProduct= seckillProductService.getSeckillProductBySkuId(skuId);
            //d.当前时间如果在秒杀时间范围之内 则生成抢购码
            Date currentTime = new Date();
            if(DateUtil.dateCompare(seckillProduct.getStartTime(),currentTime)&&
                    DateUtil.dateCompare(currentTime,seckillProduct.getEndTime())){
                //e.抢购码最好加个密
                String secKillCode = MD5.encrypt(userId);
                return RetVal.ok(secKillCode);
            }
        }
        return RetVal.fail().message("获取抢购码失败，请先登录");
    }
    //4.秒杀预下单
    @PostMapping("/prepareSeckill/{skuId}")
    public RetVal prepareSeckill(@PathVariable Long skuId,String seckillCode,HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //判断抢购码是否匹配
        if (!MD5.encrypt(userId).equals(seckillCode)){
            //不匹配则 返回请求不合法
            return RetVal.build(null, RetValCodeEnum.SECKILL_ILLEGAL);
        }
        //判断商品是否可以进行秒杀
        String status = (String)redisTemplate.opsForValue().get(RedisConst.SECKILL_STATE_PREFIX+skuId);
        if (StringUtils.isEmpty(status)){//状态为空 则返回请求不合法
            return RetVal.build(null,RetValCodeEnum.SECKILL_ILLEGAL);
        }
        if (RedisConst.CAN_SECKILL.equals(status)){//状态值为1  可以进行秒杀
            //把秒杀用户id和商品skuId  利用rabbitmq发送消息
            UserSeckillSkuInfo userSeckillSkuInfo = new UserSeckillSkuInfo();
            userSeckillSkuInfo.setSkuId(skuId);
            userSeckillSkuInfo.setUserId(userId);
            rabbitTemplate.convertAndSend(MqConst.PREPARE_SECKILL_EXCHANGE,MqConst.PREPARE_SECKILL_ROUTE_KEY,userSeckillSkuInfo);
        }else{
            //秒杀商品已经卖完
            return RetVal.build(null,RetValCodeEnum.SECKILL_FINISH);
        }
        return RetVal.ok();
    }
    //5.判断用户是否有抢购的资格
    @GetMapping(value = "/hasQualified/{skuId}")
    public RetVal hasQualified(@PathVariable Long skuId,HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        return seckillProductService.hasQualified(skuId,userId);
    }
    //6.秒杀商品确认信息
    @GetMapping("/seckillConfirm")
    public RetVal seckillConfirm(HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //获取秒杀到的预售商品订单信息
        PrepareSeckillOrder prepareSeckillOrder = (PrepareSeckillOrder) redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).get(userId);
        if (prepareSeckillOrder == null){
            return RetVal.fail().message("请求非法!");
        }
        //获取用户的地址信息
        List<UserAddress> userAddressList = userFeignClient.queryAddressByUserId(userId);
        //获取用户秒杀的那个商品
        SeckillProduct seckillProduct = prepareSeckillOrder.getSeckillProduct();
        //获取用户秒杀的商品详情信息
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setSkuId(seckillProduct.getSkuId());
        orderDetail.setSkuName(seckillProduct.getSkuName());
        orderDetail.setImgUrl(seckillProduct.getSkuDefaultImg());
        orderDetail.setSkuNum(prepareSeckillOrder.getBuyNum()+"");
        orderDetail.setOrderPrice(seckillProduct.getCostPrice());
        //返回前端的是list
        List<OrderDetail> orderDetailList = new ArrayList<>();
        orderDetailList.add(orderDetail);
        //将数据封装为map 返回给页面
        Map<String, Object> map = new HashMap<>();
        map.put("orderDetailList",orderDetailList);
        map.put("userAddressList",userAddressList);
        map.put("totalMoney",seckillProduct.getCostPrice());

        return RetVal.ok(map);
    }
    //7.保存秒杀订单的信息
    @PostMapping("/submitSecKillOrder")
    public RetVal submitSecKillOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //判断用户是否有预订单
        PrepareSeckillOrder prepareSeckillOrder = (PrepareSeckillOrder)redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).get(userId);
        if (prepareSeckillOrder == null){
            return RetVal.fail().message("非法请求!");
        }
        //调用order微服务 进行订单的保存
        Long orderId = orderFeignClient.saveOrderInfo(orderInfo);
        if (orderId == null){
            return RetVal.fail().message("非法请求!");
        }
        //根据userId删除redis中的预订单
        redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).delete(userId);
        //将用户的订单信息保存在redis中
        redisTemplate.boundHashOps(RedisConst.BOUGHT_SECKILL_USER_ORDER).put(userId,orderId);
        //返回用户id给页面显示
        return RetVal.ok(orderId);
    }

}

